unit uPreviousInstance;

interface

procedure PreviousInstance(appName: String);
var mainWindowHWND: PInteger;

implementation

uses SysUtils, Windows, Forms, Messages, Classes;

var mapHandle: THandle;

//this code sends current instance commandline parameters to previous instance
procedure PreviousInstance(appName: String);
var name:String;
var cs: PCopyDataStruct;
var sl: TStringList;
var i: Integer;
begin
  name := StringReplace(appName, ':', '', [rfReplaceAll]);
  name := StringReplace(name, '\', '', [rfReplaceAll]);

  mapHandle := CreateFileMapping($FFFFFFFF, nil, PAGE_READWRITE, 0,
      sizeOf(Integer), PChar(name));

  if mapHandle = 0 then
    RaiseLastOSError
  else if GetLastError <> ERROR_ALREADY_EXISTS then begin
    mainWindowHWND := MapViewOfFile(mapHandle, FILE_MAP_ALL_ACCESS, 0, 0,
      SizeOf(mainWindowHWND));
  end
  else begin //file exists
    mainWindowHWND := MapViewOfFile(mapHandle, FILE_MAP_ALL_ACCESS, 0, 0,
      SizeOf(mainWindowHWND));
    //send commandline
    GetMem(cs, sizeOf(TCopyDataStruct));
    sl := TStringList.Create;
    try
      if ParamCount > 0 then begin
        for i := 1 to ParamCount do
          sl.Add(ParamStr(i))
      end
      else
        sl.Add('/Restore');
    finally
      name := sl.Text;
      FreeAndNil(sl);
    end;

    with cs^ do begin
      dwData := 0;
      cbData := Length(name);
      lpData := PChar(name);
    end;

    SendMessage(mainWindowHWND^, WM_COPYDATA, Application.Handle, Integer(cs));
    FreeMem(cs);
  end;
end;

initialization
finalization
  UnmapViewOfFile(mainWindowHWND);
  CloseHandle(mapHandle);
end.
